
import * as THREE from '../../build/three.module.js';
import * as Vector2 from '../../build/three.module.js';
// import { GLTFLoader } from '../../jsm/loaders/GLTFLoader.js';
import { FBXLoader } from '../../jsm/loaders/FBXLoader.js';
import { OrbitControls } from '../../jsm/controls/OrbitControls.js';
// import { OrbitControls } from '../../jsm/controls/OrbitControls.js';
import { TransformControls, } from '../../jsm/controls/TransformControls.js'

import dat from '../../jsm/libs/dat.gui.module.js'

// var modelPath = '../../model/monkey.gltf';
// var modelPath = '../../model/10kV-transfer-inside.gltf';
// var modelPath = '../../model/J5-inside.gltf';
// var modelPath = '../../model/220kV-3-main-transfer.gltf';
// var modelPath = '../../model/guangfu-test.gltf';

var containerDom = document.querySelector("#container");

var width = window.innerWidth,
  height = window.innerHeight;

// Create a renderer and add it to the DOM.
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.setClearColor(0xcccccc);
//document.body.appendChild(renderer.domElement);
containerDom.appendChild(renderer.domElement);
// Create the scene 
var scene = new THREE.Scene();

// Create a camera
function camera_init() {

  var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000);
  //var camera = new THREE.OrthographicCamera(-1000,1000,1000,-1000,0.1,10000);
  camera.position.z = 50;
  scene.add(camera);
  return camera;
}
var camera = camera_init();

// Create a light, set its position, and add it to the scene.
function light_init() {
  var light = new THREE.PointLight(0xffffff);
  light.position.set(100, 100, 100);
  light.castShadow = true;
  light.shadow.mapSize = new THREE.Vector2(1024, 1024);
  light.shadow.camera.far = 500;
  light.shadow.camera.near = 40;
  light.intensity = 0;
  scene.add(light);
  return light;
}

function directionLight_init(){
  var directionLight = new THREE.DirectionalLight(0xffffff,2);
  directionLight.castShadow = true;
  directionLight.shadow.mapSize.width = 1024;
  directionLight.shadow.mapSize.height = 1024;
  directionLight.position.set(50,50,100);
  scene.add(directionLight);
  return directionLight;
}


// Add OrbitControls so that we can pan around with the mouse. 
function controller_init(camera) {
  // Add OrbitControls so that we can pan around with the mouse.
  var controls = new OrbitControls(camera, renderer.domElement);
  return controls;
}

// Add axes
function axes_init() {
  // Add axes  坐标创建
  var axes = new THREE.AxisHelper(50);
  scene.add(axes);
  return axes;
}

//fbx loader
function fbx_Model_Loader(modelPath) {

  // var theMaterial = new THREE.MeshLambertMaterial({ color: 0xf22fff,side:THREE.DoubleSide });
  // theMaterial.castShadow = true;
  // theMaterial.receiveShadow = true;

  var groundMaterial = new THREE.MeshLambertMaterial({ color: 0xbbbbbb, side: THREE.DoubleSide });
  groundMaterial.castShadow = true;
  groundMaterial.receiveShadow = true;

  var fbxGroup = new THREE.Group();
  var loader = new FBXLoader();
  loader.load(modelPath, function (object) {
    object.traverse(function (child) {
      // if ( child.isMesh )
      if (1 === 1) {
        child.castShadow = true;
        child.receiveShadow = true;
      }
      if (child instanceof THREE.Mesh && !child.name.indexOf('_')) {
        var theMaterial = new THREE.MeshLambertMaterial({ color: 0xf22fff, side: THREE.DoubleSide });
        theMaterial.castShadow = true;
        theMaterial.receiveShadow = true;
        child.material = theMaterial;
        //console.log( child.name)
      }
      else {
        child.material = groundMaterial;
      }
    });
    fbxGroup.add(object);

    // scene.add( object );  
    // object.position.set(0.0,-4500, -0);
    // object.rotation.x = Math.PI*0.5;
    // object.rotation.y = Math.PI  ;   

  });
  scene.add(fbxGroup);

  return fbxGroup;
}

//用于存储上一次点击的内容
var lastObjUUID = 0;
var lastColor;

//===============================================================================================================================
function transControl_init() {
  const transControls = new TransformControls(camera, renderer.domElement);
  // const target = new Object3D();
  // transControls.attach(target);
  // scene.add(target);
  scene.add(transControls);

  return transControls;
}

var transControls = transControl_init();

//变换时锁定
let transing = false;
transControls.addEventListener('mouseDown', event => {
  transing = true;
  console.log("lock-trans-down");
});

document.addEventListener('keyup', event => {
  console.log(event.key);
  if (event.key === 'g') {
    transControls.mode = "translate";
    console.log("to-translate");
    return false;
  }
  if (event.key === 's') {
    transControls.mode = "scale";
    console.log("to-scale");
    return false;
  }
  if (event.key === 'r') {
    transControls.mode = "rotate";
    console.log("to-rotate");
    return false;
  }
});

//===============================================================================================================================
//
containerDom.onclick = select_object;
function select_object(e) {
  e.preventDefault();

  var selObj;
  var objects = scene.children;
  var allObjs = new Array();

  objects.forEach(obj => {
    if (obj.type === 'Group') {
      var len = obj.children.length;
      //此处需要深入内部将载入模型的各个子模型拿出来
      obj.children.forEach(function (child, i) {
        console.log("obj-ch\t" + child.children.length);
        child.children.forEach(chd => { allObjs.push(chd); });
      });
    }
  });
  objects = allObjs;
  //根据先前选择的物体信息还原先前颜色
  objects.forEach(obj => {
    if (obj.uuid == lastObjUUID) {
      obj.material.color.set(lastColor);
      console.log(lastColor);
    }
  });
  //将鼠标点击位置的屏幕坐标转成threejs中的标准坐标,具体解释见代码释义
  var mousex = (e.clientX / window.innerWidth) * 2 - 1;
  var mousey = -(e.clientY / window.innerHeight) * 2 + 1;
  //新建一个三维单位向量 假设z方向就是0.5
  //根据照相机，把这个向量转换到视点坐标系
  // var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5).unproject(camera);
  var vector = new THREE.Vector3(mousex, mousey, 0.5).unproject(camera);

  //在视点坐标系中形成射线,射线的起点向量是照相机， 射线的方向向量是照相机到点击的点，这个向量应该归一标准化。
  var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());

  //射线和模型求交，选中一系列直线
  var intersects = raycaster.intersectObjects(objects);
  console.log('intersrcts=' + intersects)

  if (intersects.length > 0) {
    //选中第一个射线相交的物体
    // SELECTED = intersects[0].object;
    var intersected = intersects[0].object;
    selObj=intersected;
    //console.log("cool")
    console.log(intersected)
    console.log(intersected.rotation)

    //记录所选物体以及颜色
    lastObjUUID = intersected.uuid;
    lastColor = intersected.material.color.clone();

    //改变选中物体的颜色
    // intersected.material.color.set(0xff00ff *Math.random() );
    intersected.material.color.set(0x2222ff);
    //transControls.attach(intersected);
  }
  else {
    console.log("没捕获到对象");
  }
  //----------------------------------------------------------------
  {
    const mouse = new THREE.Vector2(mousex, mousey);
    if (transing) { transing = false; return false; }  //变换时锁定 若在变换则依靠结束的click解锁
    raycaster.setFromCamera(mouse, camera);

    //去除先前的变换控制器的影响
    scene.remove(transControls);
    var intersection = raycaster.intersectObjects(objects);
    //选择完成后再次加入控制器
    scene.add(transControls); 

    transControls.attach(selObj.Mesh);
    console.log('EEEE:',selObj);
   

  }


}
//===============================================================================================================================


//===============================================================================================================================

var controls = controller_init(camera);
var light = light_init();
var directLight =directionLight_init();
var axis = axes_init();
var controls = controller_init(camera);
var fbxGroup = fbx_Model_Loader('../../model/guangfu-fbx.fbx');
fbxGroup.position.set(0.0, -4500, -0);
fbxGroup.rotation.x = Math.PI * 0.5;
fbxGroup.rotation.y = Math.PI;

var pointLightHelper = new THREE.PointLightHelper(light);
scene.add(pointLightHelper);
var directLightHelper = new THREE.DirectionalLightHelper(directLight);
scene.add(directLightHelper);
//===============================================================================================================================

var gui = new dat.GUI(); 
{
  var shaderFolder = gui.addFolder("linghtFolder");
  var lightProperty= new function () {
     
    this.lightPosX = 20;
    this.lightPosY = 20;
    this.lightPosZ = 20;
 
  };   
  var directLightProperty= new function () { 
    this.directLightPosX = 50;
    this.directLightPosY = 50;
    this.directLightPosZ = 100;
    this.directLightIntens = 20;
  };   
  
  shaderFolder.add(lightProperty, 'lightPosX',-500.0,500.0).onChange(value=>{
    light.position.x  = value; 
  }); 
  shaderFolder.add(lightProperty, 'lightPosY',-500,500.0).onChange(value=>{
    light.position.y  = value;  
  }); 
  shaderFolder.add(lightProperty, 'lightPosZ',-500.0,500.0).onChange(value=>{
    light.position.z = value; 
  }); 

  
  shaderFolder.add(directLightProperty, 'directLightPosX',-2000.0,2000.0).onChange(value=>{
    directLight.position.x  = value; 
  }); 
  shaderFolder.add(directLightProperty, 'directLightPosY',-0.0,2000.0).onChange(value=>{
    directLight.position.y  = value; 
  }); 
  shaderFolder.add(directLightProperty, 'directLightPosZ',-2000.0,2000.0).onChange(value=>{
    directLight.position.z  = value; 
  }); 
  shaderFolder.add(directLightProperty, 'directLightIntens',0.0,3.0).onChange(value=>{
    directLight.intensity  = value; 
  }); 
}


//===============================================================================================================================
resize();
animate();
window.addEventListener('resize', resize);

function resize() {
  let w = window.innerWidth;
  let h = window.innerHeight;

  renderer.setSize(w, h);
  camera.aspect = w / h;
  camera.updateProjectionMatrix();
}

// Renders the scene
function animate() {

  light.position.y += 0.1;
  //fbxGroup.position.y-=5;
  //console.log( fbxGroup.position.y)
  //fbxGroup.rotation.y += 0.1;
  // console.log(gltfGroup.rotation.x);
  pointLightHelper.update();
  directLightHelper.update();

  requestAnimationFrame(animate);

  renderer.render(scene, camera);
  controls.update();

}
